package com.hulk.ratel.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.google.common.base.Strings;
import com.google.common.eventbus.EventBus;
import com.hulk.ratel.common.constant.Constant;
import com.hulk.ratel.common.constant.enums.BussErrCode;
import com.hulk.ratel.common.exception.ServiceRteException;
import com.hulk.ratel.common.tool.ValidatorTool;
import com.hulk.ratel.manage.commoncache.*;
import com.hulk.ratel.manage.commonutil.ContentUtil;
import com.hulk.ratel.persistence.entity.*;
import com.hulk.ratel.persistence.repository.TLogTxnPayRecordRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Optional;

/**
 * @Author: hulk
 * @E-mail: 29572320@qq.com
 * @Date: Create in 2018/8/31 下午10:20
 * @Version: 1.0.0
 * @Modify by:
 * Class description
 */
@Slf4j
@Service(value = "absService")
public abstract class AbsServiceImpl {


    @Autowired
    protected EventBus eventBus;
    @Autowired
    protected ContentUtil contentUtil;
    @Autowired
    protected SecurityPartnerCache securityPartnerCache;
    @Autowired
    protected TLogTxnPayRecordRepository logTxnPayRecordRepository;
    @Autowired
    protected PartnerInfoCache partnerInfoCache;
    @Autowired
    protected PartnerKeyCache partnerKeyCache;
    @Autowired
    protected TxnCodeCache txnCodeCache;
    @Autowired
    protected PayOrgInfoCache payOrgInfoCache;
    @Autowired
    protected DictCodeCache dictCodeCache;
    @Autowired
    protected DictInfoCache dictInfoCache;




   /* protected void unifyCheck(InitiativeScanPayReqDTO dto, String workId) {
        String txnCode = dto.getHead().getTxnCode();
        String partnerNo =dto.getHead().getPartnerNo();
        String traceId =dto.getHead().getTraceId();

        //合作方信息校验
        TPartnerInfo partnerInfo = checkPartner(partnerNo, workId);
        //交易权限校验
        TTxncode txnCodeInfo = checkTxnCode(txnCode, workId);
        //交易重复性校验
        checkTxnLog(traceId, workId, partnerNo);
    }*/


    @Nonnull
    protected String validateBean(Object o, String workId) {
        String validateResult = ValidatorTool.validateBean(o);
        if (!Strings.isNullOrEmpty(validateResult)) {
            throw new ServiceRteException(workId, BussErrCode.E_100001.getErrCode(), validateResult);
        }
        return validateResult;
    }

    /**
     * 查询合作方信息
     */
    @Nonnull
    protected TPartnerInfo checkPartner(String partnerNo, String workId) {
        TPartnerInfo partner = Optional.ofNullable(partnerInfoCache.findPartnerInfo(workId, partnerNo)).orElseThrow(()->new ServiceRteException(workId, BussErrCode.E_100002));
        if (Strings.isNullOrEmpty(partner.getPartnerType())) {
            throw new ServiceRteException(workId, BussErrCode.E_200153.getErrCode(), BussErrCode.E_200153.getErrDesc());
        }
        log.info("partnerNo:{} workId：{} 合作方信息校验通过!", partnerNo, workId);
        return partner;
    }

    /**
     * 交易权限信息
     */
    @Nonnull
    protected TTxncode checkTxnCode(String txnCode, String workId) {
        TTxncode paraTxncode =  Optional.ofNullable(txnCodeCache.findTxnCodeInfo(workId, txnCode)).orElseThrow(()->new ServiceRteException(workId, BussErrCode.E_100009));
        log.info("txnCode：{} workId：{} 交易权限校验通过!", txnCode, workId);
        return paraTxncode;
    }

    /**
     * 支付机构查询
     */
    @Nonnull
    protected TPayorgInfo queryPayOrgInfo( String payOrgCode,String workId) {
        TPayorgInfo payOrg =  Optional.ofNullable(payOrgInfoCache.findPayorgInfo(workId, payOrgCode)).orElseThrow(()->{ log.error("workId:{} 查询支付机构：{} 信息不存在！", workId, payOrgCode);return new ServiceRteException(workId, BussErrCode.E_200105);});
        log.info("workId:{} 查询支付机构：{} 信息存在！", workId, payOrgCode);
        return payOrg;
    }
    
    /**
     * 支付流水重复校验
     */
    @Nonnull
    protected void checkTxnLog(String partnerNo,String tradeNo, String workId) {
        TLogTxnPayRecord param = new TLogTxnPayRecord();
        param.setTraceId(tradeNo);
        param.setPartnerNo(partnerNo);
        Wrapper<TLogTxnPayRecord> queryTxnPayRecord = new EntityWrapper<>(param);
        int count = logTxnPayRecordRepository.selectCount(queryTxnPayRecord);
        if (Constant.ZERO_INT < count) {
            log.error("支付流水重复校验不通过！ tradeNo：{} workId:{}", tradeNo, workId);
            throw new ServiceRteException(workId, BussErrCode.E_200106.getErrCode(), BussErrCode.E_200106.getErrDesc());
        }
        log.info("支付流水重复校验通过！ partnerNo:{} tradeNo:{} workId:{}", partnerNo, tradeNo, workId);
    }
    
    /**
     * 查询字典信息
     */
    @Nonnull
    protected List<TDictCode> queryDictInfo( String code,String workId) {
        TDictInfo dictInfo = dictInfoCache.findDictInfo(workId, code);
        if (null != dictInfo) {
            return  Optional.of(dictCodeCache.findDictCodes(workId, dictInfo.getDictId())).get();
        } else {
            return null;
        }
    }
}
